#include "XMLParser.h"
#include "LoaderXML.h"


XMLParser::XMLParser()
{
	this ->_ptr["channel"] = &XMLParser::channelTag;
	this ->_ptr["title"] = &XMLParser::titleTag;
	this ->_ptr["description"] = &XMLParser::descrTag;
	this ->_ptr["link"] = &XMLParser::linkTag;
	this ->_ptr["item"] = &XMLParser::itemTag;
}

channel		XMLParser::getFeed()
{
	return this->_feedContent;
}

std::string	XMLParser::getTagName()
{
	std::string	ret = "";

	this->parser->readUntil('<');
	this->parser->beginCapture("tagName");
	this->parser->readUntil('>');
	this->parser->endCapture("tagName", ret);
	return ret;
}

bool	XMLParser::channelTag(bool, Item *)
{
	this->isChan = true;
	this->isItem = false;
	return true;
}

bool	XMLParser::itemTag(bool, Item *)
{
	this->isChan = false;
	this->isItem = true;
	return true;
}

bool	XMLParser::titleTag(bool isCreated, Item *item)
{
	std::string	title;
	std::string	tagName;

	title = this->parser->getTagContent();
	if (this->isChan)
		this->_feedContent.setTitle(title);
	else if (this->isItem)
	{
		bool	push = false;
		Item	*it = item;
		if (!isCreated)
		{
			it = new Item;
			push = true;
		}

		if (push)
			this->_feedContent.addItem(it);
		it->setTitle(title);
		tagName = this->getTagName();
		while (tagName.substr(0, tagName.find(">")) != "/item" && !this->parser->readEOF())
		{
			//std::cout <<  "[TITLE]" << tagName.substr(0, tagName.find(">")) << "[/TAG]" << std::endl;
			if (this->_ptr[tagName.substr(0, tagName.find(">"))])
				return (this->*(this->_ptr[tagName.substr(0, tagName.find(">"))]))(true, it);
			tagName = this->getTagName();
		}
		return true;
	}
	return false;
}

bool	XMLParser::descrTag(bool isCreated, Item *item)
{
	std::string	descr;
	std::string	tagName;

	descr = this->parser->getTagContent();
	if (this->isChan)
		this->_feedContent.setDescription(descr);
	else if (this->isItem)
	{
		bool	push = false;
		Item	*it = item;
		if (!isCreated)
		{
			it = new Item;
			push = true;
		}

		if (push)
			this->_feedContent.addItem(it);
		it->setDescription(descr);
		tagName = this->getTagName();
		while (tagName.substr(0, tagName.find(">")) != "/item" && !this->parser->readEOF())
		{
			//std::cout <<  "[DESCR]" << tagName.substr(0, tagName.find(">")) << "[/DESCR]" << std::endl;
			if (this->_ptr[tagName.substr(0, tagName.find(">"))])
				 return (this->*(this->_ptr[tagName.substr(0, tagName.find(">"))]))(true, it);
			tagName = this->getTagName();
		}
		return true;
	}
	return false;
}

bool	XMLParser::linkTag(bool isCreated, Item *item)
{
	std::string	link;
	std::string	tagName;

	link = this->parser->getTagContent();
	if (this->isChan)
		this->_feedContent.setLink(link);
	else if (this->isItem)
	{
		bool	push = false;
		Item	*it = item;
		if (!isCreated)
		{
			push = true;		
			it = new Item;
		}

		if (push)
		this->_feedContent.addItem(it);
		it->setLink(link);
		tagName = this->getTagName();
		while (tagName.substr(0, tagName.find(">")) != "/item" && !this->parser->readEOF())
		{
			//std::cout <<  "[LINK]" << tagName.substr(0, tagName.find(">")) << "[/TAG]" << std::endl;
			if (this->_ptr[tagName.substr(0, tagName.find(">"))])
				return (this->*(this->_ptr[tagName.substr(0, tagName.find(">"))]))(true, it);
			tagName = this->getTagName();
		}
		return true;
	}
	return false;
}


void		XMLParser::parseFile(const std::string& file)
{
	LoaderXML		feed;
	std::string		tag = "";

	this->parser = new ConsumerParser(feed);
	feed.loadFile(file.c_str());
	while (!parser->readEOF() && tag.substr(0, tag.find(">")) != "/rss")
	{
		tag = this->getTagName();
		if (this->_ptr[tag.substr(0, tag.find(">"))])
			(this->*(this->_ptr[tag.substr(0, tag.find(">"))]))(false, NULL);
	}
}
